<template>
	<div class="container">
		<h2 style="text-align: center;">{{ id ? '修改' : '创建' }}机械申请</h2>
		<a-form ref="formRef" :model="formState" @finish="saveMachineapply">
			<a-row :gutter="20">
				<a-col :span="12">
					<a-form-item label="选择项目" name="project_id" :rules="{ required: true, message: '请选择项目' }">
						<a-select v-model:value="formState.project_id" :show-search="true" placeholder="请选择项目" :options="projectOptions" option-filter-prop="label" @change="changeProject"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="12">
					<a-form-item label="送达地址" name="deliver_address" :rules="{ required: true, message: '请输入送达地址' }">
						<a-input v-model:value="formState.deliver_address" readonly="readonly" placeholder="请输入送达地址" disabled />
					</a-form-item>
				</a-col>
				<a-col :span="12">
					<a-form-item label="现场联系人" name="receiver_id" :rules="{ required: true, message: '请选择接收联系人' }">
						<a-select v-model:value="formState.receiver_id" :show-search="true" placeholder="请选择接收联系人" :options="userlist" option-filter-prop="label" @change="changeUser"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="12">
					<a-form-item label="联系人电话" name="receiver_tel" :rules="{ required: true, message: '请输入联系人电话' }">
						<a-input v-model:value="formState.receiver_tel" placeholder="请输入联系人电话" readonly="readonly" disabled />
					</a-form-item>
				</a-col>
				<a-col :span="12">
					<a-form-item label="送达日期" name="deliver_time" :rules="{ required: true, message: '请输入送达日期' }">
						<a-date-picker v-model:value="formState.deliver_time" value-format="YYYY-MM-DD HH:mm:ss" show-time style="width:100%" />
					</a-form-item>
				</a-col>

				<a-col :span="24">
					<h4>本次采购物资清单</h4>
					<div class="table-toolbar mb-3">
						<a-space>
							<a-button type="primary" :disabled="formState.materials.length >=1" @click="addMaterialModel">
								<plus-outlined />新增
							</a-button>
							<a-button class="cache-btn" @click="handleCache">
								<DeliveredProcedureOutlined />暂存
							</a-button>
						</a-space>
					</div>

					<a-table :data-source="formState.materials" :columns="planMaterialColumns" :row-key="(record) => record.key">
						<template #bodyCell="{ column, record, index }">
							<template v-if="column.dataIndex === 'id'">{{ index + 1 }}</template>
							<template v-if="column.dataIndex === 'name'">
								<a-form-item :name="['materials', index, 'source_id']" :rules="{ required: true, message: '请选择' }">
									<a-tree-select v-model:value="formState.materials[index].source_id" :show-search="true" placeholder="请选择" allow-clear tree-default-expand-all :tree-data="sourceOptions" tree-node-filter-prop="label" style="width:100%" @change="handleSourceChange(record)">
										<template #title="{ label }">{{ label }}</template>
									</a-tree-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'model'">
								<a-form-item :name="['materials', index, 'model']" :rules="{ required: true, message: '请选择规格' }">
									<a-select v-model:value="formState.materials[index].model" :show-search="true" placeholder="请选择" :options="modelOptions[record.source_id]" allow-clear :field-names="{ value: 'model', label: 'modelName' }" style="width:100%" @change="(model) => handleModelChange(record, model)"></a-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'use_time'">
								<a-form-item :name="['materials', index, 'use_time']" :rules="{ required: true, message: '请输入' }">
									<a-input-number v-model:value="formState.materials[index].use_time" placeholder="请输入" @change="checkUseTime(record)" />
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'time_unit'">
								<a-form-item :name="['materials', index, 'time_unit']" :rules="{ required: true, message: '请选择' }">
									<a-select v-model:value="formState.materials[index].time_unit" placeholder="请选择" :options="timeUnitOptions[record.id]" :field-names="{ value: 'name' }" style="width:100%"></a-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'unit'">
								<a-form-item :name="['materials', index, 'unit']" :rules="{ required: true, message: '请选择计量单位' }">
									<a-select v-model:value="formState.materials[index].unit" :show-search="true" placeholder="请选择" :options="unitOptions[`${record.source_id}_${record.model}`]" :field-names="{ value: 'name' }" style="width:100%" @change="handleUnitChange(record, unitOptions[`${record.source_id}_${record.model}`])"></a-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'quantity'">
								<a-form-item :name="['materials', index, 'quantity']" :rules="{ required: true, message: '请输入数量' }">
									<a-input v-model:value="formState.materials[index].quantity" placeholder="请输入数量" disabled />
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'use_date'">
								<a-form-item :name="['materials', index, 'use_date']">
									<a-date-picker v-model:value="formState.materials[index].use_date" value-format="YYYY-MM-DD HH:mm:ss" show-time style="width:100%" />
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'useFor'">
								<a-form-item :name="['materials', index, 'useFor']">
									<a-input v-model:value="formState.materials[index].useFor" placeholder="请输入" />
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'memo'">
								<a-form-item :name="['materials', index, 'memo']">
									<a-input v-model:value="formState.materials[index].memo" placeholder="请输入备注" />
								</a-form-item>
							</template>
							<template v-else-if="column.key === 'operation'">
								<a-space>
									<a-popconfirm title="确定要删除当前材料吗？" ok-text="是" cancel-text="否" @confirm="deleteMaterialModel(record.key)">
										<a-button type="link" style="color:#ff7875">
											<delete-outlined />删除
										</a-button>
									</a-popconfirm>
								</a-space>
							</template>
						</template>
					</a-table>
				</a-col>
				<a-col :span="24" style="margin-top: 24px;">
					<a-form-item label="备注" name="memo">
						<a-textarea v-model:value="formState.memo" :auto-size="{ minRows: 4, maxRows: 6 }"></a-textarea>
					</a-form-item>
				</a-col>
			</a-row>

			<a-row :gutter="20">
				<a-col :span="24" class="py-4 text-center">
					<a-space>
						<a-button class="cache-btn" @click="handleCache">
							<DeliveredProcedureOutlined />暂存
						</a-button>
						<a-button v-if="!formState.id || ![0,1,2].includes(formState.workflow_status)" type="primary" html-type="submit">
							<save-outlined />保存
						</a-button>
						<a-workflow v-if="formState.id" v-model:status="formState.workflow_status" module="machineapply" :target-id="formState.id" :project-id="formState.project_id" :code="formState.code" :user-id="formState.apply_id" @submit="submitPurchase"></a-workflow>
						<a-button @click="closeTab('/machineapply')">
							<close-outlined />关闭
						</a-button>
					</a-space>
				</a-col>
			</a-row>
		</a-form>
	</div>
</template>

<script setup>
import { ref, computed, onMounted, getCurrentInstance, inject } from "vue";
import { DeleteOutlined, SaveOutlined, DeliveredProcedureOutlined, CloseOutlined, PlusOutlined } from "@ant-design/icons-vue";
import { post, listToTree } from "../utils";
import { useRoute } from "vue-router";
import { add, subtract } from "@/utils/operation.js";
import { AWorkflow } from "@/components/index.js";
//缓存数据
const handleCache = () => {
	// console.log(formState.value);
	localStorage.setItem("machineapply-save", JSON.stringify(formState.value));
	proxy.$message.success("缓存成功");
};
const route = useRoute();
const id = computed(() => {
	return route.params.id || 0;
});
const formState = ref({ materials: [] });
const contractlist = ref([]); //	合同列表
const formRef = ref();
const { proxy } = getCurrentInstance();
const addMaterialModel = () => {
	formState.value.materials.push({
		key: formState.value.materials.length,
		quantity: 1
	});
};

const planMaterialColumns = [
	{
		title: "序号",
		dataIndex: "id",
		width: 60,
		align: "center"
	},
	{
		title: "机械名称",
		dataIndex: "name",
		ellipsis: true
	},
	{
		title: "规格型号",
		dataIndex: "model",
		align: "center",
		width: 150
	},
	{
		title: "计量单位",
		dataIndex: "unit",
		align: "center"
	},
	{
		title: "数量",
		dataIndex: "quantity",
		align: "center"
	},
	{
		title: "物资数量余量",
		dataIndex: "contractQuantity",
		align: "center"
	},
	{
		title: "使用时长",
		dataIndex: "use_time",
		align: "center"
	},
	{
		title: "时长余量",
		dataIndex: "contractUseTime",
		align: "center"
	},
	// {
	// 	title: "时长单位",
	// 	dataIndex: "time_unit",
	// 	align: "center"
	// },
	{
		title: "工作内容",
		dataIndex: "useFor",
		align: "center"
	},
	{
		title: "使用时间",
		dataIndex: "use_date",
		align: "center",
		width: 190
	},
	{
		title: "备注",
		dataIndex: "memo",
		align: "center"
	},
	{
		title: "操作",
		key: "operation",
		sorter: false,
		fixed: "right",
		width: 80,
		align: "center"
	}
];

//projectOptions
const projectOptions = ref([]);
const userlist = ref([]);
post("department/projects?type=3").then(({ data }) => {
	projectOptions.value = data.map(d => {
		return {
			value: d.id,
			label: d.name,
			leader: d.leader, 
			phone: d.phone,
			address: d.address
		};
	});
});

const materialInfo = ref({});
const sourceOptions = ref([]);
const modelOptions = ref({});
const unitOptions = ref({});
const timeUnitOptions = ref({});
const changeProject = project_id => {
	formState.value.receiver_id = null;
	return new Promise((resolve, reject) => {
		post("project/user", { project_id, scene: "main", status: '1' }).then(data => {
			userlist.value = data.map(d => ({
				label: d.fullname || d.username,
				value: d.id,
				mobile: d.mobile
			}));
		});
		post("contract/all", { project_id: project_id, types: "3" }).then(data => {
			materialInfo.value = {};
			sourceOptions.value = [];
			modelOptions.value = {};
			unitOptions.value = {};
			timeUnitOptions.value = {};

			if (!data.length) {
				contractlist.value = [];
				formState.value.project_id = null;
				proxy.$message.error("当前项目尚未绑定合同");
				return;
			}

			contractlist.value = data;
			// 物资唯一 按照物资分组统计
			const materials = data
				.map(item => item.materials)
				.reduce((res, curr) => {
					res.push(...curr);
					return res;
				}, []);
			materialInfo.value = materials.reduce((res, curr) => {
				if (!res[curr.id]) {
					const model = curr.attr ? `${curr.model}（${curr.attr}）` : curr.model;
					res[curr.id] = {
						name: curr.name,
						model: model, // 型号
						unit: curr.ContractMaterial.unit, // 单位 物资中的单位有问题，显示为id
						time_unit: curr.ContractMaterial.time_unit,
						source_id: curr.source_id, // 字典物料id
						quantity: 0 // 当前物资数量
					};
				}
				// 物资数量汇总
				const quantity = Number(curr.ContractMaterial.quantity);
				res[curr.id].quantity += isNaN(quantity) ? 0 : quantity;
				return res;
			}, {});

			sourceOptions.value = Object.keys(materialInfo.value)
				.map(materialId => {
					return {
						value: materialInfo.value[materialId].source_id,
						label: materialInfo.value[materialId].name
					};
				})
				.reduce((res, curr) => {
					const ids = res.map(item => item.value);
					if (!ids.includes(curr.value)) {
						res.push(curr);
					}
					return res;
				}, []);

			const sourceIds = sourceOptions.value.map(item => item.value);
			// modelOptions.value = sourceIds.reduce((res, sourceId) => {
			// 	const materialIds = Object.keys(materialInfo.value).filter(materialId => materialInfo.value[materialId].source_id === sourceId);
			// 	res[sourceId] = materialIds.map(materialId => {
			// 		return {
			// 			id: Number(materialId),
			// 			model: materialInfo.value[materialId].model
			// 		};
			// 	});
			// 	return res;
			// }, {});

			modelOptions.value = sourceIds.reduce((res, sourceId) => {
				const materials = Object.values(materialInfo.value).filter(material => material.source_id === sourceId);
				const models = Array.from(new Set(materials.map(item => item.model)));
				res[sourceId] = models.map(model => {
					return {
						model: model,
						modelName: model
					};
				});
				return res;
			}, {});

			// unitOptions.value = Object.keys(materialInfo.value).reduce((res, materialId) => {
			// 	res[materialId] = [
			// 		{
			// 			name: materialInfo.value[materialId].unit,
			// 			label: materialInfo.value[materialId].unit
			// 		}
			// 	];
			// 	return res;
			// }, {});
			timeUnitOptions.value = Object.keys(materialInfo.value).reduce((res, materialId) => {
				res[materialId] = [
					{
						name: materialInfo.value[materialId].time_unit,
						label: materialInfo.value[materialId].time_unit
					}
				];
				return res;
			}, {});

			//自动完善地址信息
			const projectInfo = projectOptions.value.find(d => d.value === project_id);
			// formState.value.receiver = null;
			// formState.value.receiver_tel = null;
			// if (!projectInfo.phone || !projectInfo.leader) {
			// 	proxy.$message.error("请到组织架构完善当前项目信息");
			// 	formState.value.project_id = null;
			// 	return resolve();
			// }
			// formState.value.receiver = projectInfo.leader;
			// formState.value.receiver_tel = projectInfo.phone;
			formState.value.deliver_address = projectInfo.address;
			resolve();
		});
	});
};

const changeUser = (userId) => {
	const user = userlist.value.find(d => d.value === userId);
	formState.value.receiver = user.label;
	formState.value.receiver_tel = user.mobile;
}

const handleSourceChange = record => {
	record.id = undefined;
	record.model = undefined;
	record.unit = undefined;
	record.time_unit = undefined;
};

const handleModelChange = (record, model) => {
	record.id = null;
	record.unit = undefined;
	record.time_unit = undefined;
	if (!timeUnitOptions.value[`${record.source_id}_${record.model}`]) {
		const list = [];
		for (const materialId in materialInfo.value) {
			const material = materialInfo.value[materialId];
			if (material.model !== model) continue;
			list.push({
				id: materialId,
				name: material.unit,
				label: material.unit
			});
		}
		unitOptions.value[`${record.source_id}_${record.model}`] = list;
	}
};

const handleUnitChange = async (record, unitOpt) => {
	if (record.unit) {
		record.id = unitOpt.filter(item => item.name === record.unit)[0].id;
		record.use_time = null;
	} else {
		return;
	}
	const supplyOrderMaterialInfos = await post(`supplyOrder/materials`, {
		contract_ids: JSON.stringify(contractlist.value.map(item => item.id)),
		material_ids: JSON.stringify([record.id])
	});
	const supplyOrderMaterialInfos2MaterialId = supplyOrderMaterialInfos.reduce((target, item) => {
		if (!target[item.material.id]) {
			target[item.material.id] = {
				ys_quantity: 0,
				use_time: 0
			};
		}
		target[item.material.id].ys_quantity = add([target[item.material.id].ys_quantity, item.ys_quantity || 0]);
		target[item.material.id].use_time = add([target[item.material.id].use_time, item.use_time || 0]);
		return target;
	}, {});
	const contractMaterialInfos2MaterialId = contractlist.value.reduce((target, item) => {
		for (const material of item.materials) {
			if (!target[material.id]) {
				target[material.id] = {
					quantity: 0,
					use_time: 0
				};
			}
			target[material.id].quantity = add([target[material.id].quantity, material.ContractMaterial?.quantity || 0]);
			target[material.id].use_time = add([parseFloat(target[material.id].use_time), parseFloat(material.ContractMaterial?.use_time) || 0]);
		}
		return target;
	}, {});
	let useTime = 0;
	if (supplyOrderMaterialInfos2MaterialId[record.id]?.ys_quantity) {
		useTime = supplyOrderMaterialInfos2MaterialId[record.id]?.use_time;
	}
	record.contractQuantity = contractMaterialInfos2MaterialId[record.id].quantity;
	record.contractUseTime = subtract([contractMaterialInfos2MaterialId[record.id].use_time, useTime] || 0);
	record.quantity = 1;
	if (record.quantity > record.contractQuantity) {
		record.quantity = null;
		record.id = null;
		record.unit = null;
		proxy.$message.error("该物资余量为0，请选择其他物料");
		return;
	}
	//当前的物资数量
	// let current_qty = 0;
	// formState.value.materials.map(d => {
	// 	if (d.id === record.id) {
	// 		current_qty = current_qty + parseFloat(d.quantity);
	// 	}
	// });
	// const purchaseHistory = await post("machineapply/all", { project_id: formState.value.project_id, material_ids: JSON.stringify([record.id]) });
	// const history_current_qty = purchaseHistory.reduce((target, item) => {
	// 	if (parseInt(item.id) === parseInt(route.params.id)) return target;
	// 	for (const material of item.materials) {
	// 		if (parseInt(material.id) !== parseInt(record.id)) {
	// 			continue;
	// 		}
	// 		target = target + parseFloat(material.MachineapplyMaterial.quantity);
	// 	}
	// 	return target;
	// }, 0);
	// // 当前物料的合同数量
	// const material = materialInfo.value[record.id];
	// if (current_qty > material.quantity - history_current_qty) {
	// 	proxy.$message.error("预约清单数量不能超过合同数量");
	// 	let now_qty = parseFloat(material.quantity) - parseFloat(history_current_qty) - parseFloat(current_qty) + parseFloat(record.quantity);
	// 	if (now_qty < 0) {
	// 		now_qty = 0;
	// 	}
	// 	record.quantity = now_qty;
	// }
};
// 时长校验
function checkUseTime(record) {
	if (!record.id) return;
	if (parseFloat(record.use_time) > parseFloat(record.contractUseTime)) {
		proxy.$message.error("使用时长不能超过时长余量");
		record.use_time = record.contractUseTime;
	}
	if (parseFloat(record.use_time) === 0) {
		record.use_time = null;
	}
	// let maxUseTime = 0;
	// for (const contract of contractlist.value) {
	// 	for (const material of contract.materials) {
	// 		if (parseInt(material.id) !== parseInt(record.id)) {
	// 			continue;
	// 		}
	// 		if (material.ContractMaterial.use_time > maxUseTime) {
	// 			maxUseTime = material.ContractMaterial.use_time;
	// 		}
	// 	}
	// }
	// if (parseFloat(record.use_time) > parseFloat(maxUseTime)) {
	// 	proxy.$message.error("使用时长不能超过合同使用时长");
	// 	record.use_time = maxUseTime;
	// }
}
onMounted(() => {
	const cacheData = localStorage.getItem("machineapply-save");
	formState.value = JSON.parse(cacheData) || formState.value;
	if (id.value) {
		post("machineapply/info", { id: id.value }).then(async data => {
			await changeProject(data.project.id);
			const supplyOrderMaterialInfos = await post(`supplyOrder/materials`, {
				contract_ids: JSON.stringify(contractlist.value.map(item => item.id)),
				material_ids: JSON.stringify(data.materials.map(item => item.id))
			});
			const supplyOrderMaterialInfos2MaterialId = supplyOrderMaterialInfos.reduce((target, item) => {
				if (!target[item.material.id]) {
					target[item.material.id] = {
						ys_quantity: 0,
						use_time: 0
					};
				}
				target[item.material.id].ys_quantity = add([target[item.material.id].ys_quantity, item.ys_quantity || 0]);
				target[item.material.id].use_time = add([target[item.material.id].use_time, item.use_time || 0]);
				return target;
			}, {});
			const contractMaterialInfos2MaterialId = contractlist.value.reduce((target, item) => {
				for (const material of item.materials) {
					if (!target[material.id]) {
						target[material.id] = {
							quantity: 0,
							use_time: 0
						};
					}
					target[material.id].quantity = add([target[material.id].quantity, material.ContractMaterial?.quantity || 0]);
					target[material.id].use_time = parseFloat(target[material.id].use_time) > parseFloat(material.ContractMaterial?.use_time) ? target[material.id].use_time : material.ContractMaterial?.use_time;
				}
				return target;
			}, {});
			data.materials = data.materials.map(item => {
				const { quantity, unit, memo, time_unit, use_time, useFor, use_date } = item.MachineapplyMaterial;
				const contractQuantity = contractMaterialInfos2MaterialId[item.id].quantity;
				const contractUseTime = subtract([contractMaterialInfos2MaterialId[item.id].use_time, supplyOrderMaterialInfos2MaterialId[item.id]?.use_time]);
				return {
					...item,
					quantity,
					unit,
					memo,
					time_unit,
					use_time,
					useFor,
					use_date,
					contractQuantity,
					contractUseTime
				};
			});
			formState.value = data;
		});
	}
});

const saveMachineapply = () => {
	formRef.value
		.validate()
		.then(() => {
			proxy.$message.destroy();
			const params = { ...formState.value };

			if (!contractlist.value.length) {
				proxy.$message.error("当前项目尚未绑定合同");
				return;
			}

			if (!params.materials.length) {
				proxy.$message.error("请添加材料清单");
				return;
			}
			const quantitys = params.materials.map(item => item.quantity);
			if (quantitys.includes(0)) {
				proxy.$message.error("材料数量不允许为0");
				return;
			}
			// 判断所有物资不能超过合同
			const sourceIds = params.materials.map(item => item.source_id);
			const targetSourceIds = Object.keys(materialInfo.value).map(materialId => materialInfo.value[materialId].source_id);
			if (sourceIds.some(sourceId => !targetSourceIds.includes(sourceId))) {
				proxy.$message.error("只能选择合同内的物资");
				return;
			}
			// 2. 判断物资数量
			const summaryRes = params.materials.reduce((res, curr) => {
				if (!res[curr.id]) {
					res[curr.id] = {
						quantity: 0
					};
				}
				res[curr.id].quantity += Number(curr.quantity);
				return res;
			}, {});

			const isValid = Object.keys(summaryRes).every(materialId => {
				return summaryRes[materialId].quantity <= materialInfo.value[materialId].quantity;
			});
			if (!isValid) {
				proxy.$message.error("物资数量不能超过合同数量");
				return;
			}

			params.materials = JSON.stringify(params.materials);
			params.contract_ids = contractlist.value.map(item => item.id).join(",");
			post("machineapply/save", params)
				.then(() => {
					if (id.value) {
						proxy.$message.success("修改成功", 1);
					} else {
						proxy.$message.success("创建成功", 1);
					}

					closeTab("/machineapply");
					localStorage.removeItem("machineapply-save");
				})
				.catch(err => {
					proxy.$message.error(err);
				});
		})
		.catch(err => {
			proxy.$message.error(err.message);
		});
};

const deleteMaterialModel = key => {
	const { materials } = formState.value;

	const index = materials.findIndex(d => d.key === key);
	if (index === false) return;
	materials.splice(index, 1);

	formState.value = {
		...formState.value,
		materials: materials.map((d, i) => {
			d.key = i;
			return d;
		})
	};
};

const submitPurchase = () => {
	proxy.$message.success("申请提交成功", 1);
	closeTab("/machineapply");
};

const closeTab = inject("closeTab");
</script>

<style scoped lang="scss">
.container {
	background: #fff;
	padding: 12px;

	h2 {
		font-size: 16px;
		font-weight: 600;
		line-height: 30px;
		margin-bottom: 20px;
	}

	h3 {
		line-height: 40px;
		font-size: 16px;
		font-weight: 400;
		margin-bottom: 20px;

		display: flex;
		align-items: center;

		&:before {
			content: "";
			display: block;
			width: 2px;
			height: 20px;
			background: rgb(24, 144, 255);
			margin-right: 10px;
		}
	}

	h4 {
		font-weight: 600;
		margin: 15px 0;
		line-height: 30px;
	}
}

:deep(.ant-table-cell) .ant-form-item {
	margin-bottom: 0;

	.ant-form-item-explain {
		position: absolute;
		bottom: -24px;
	}
}

.cache-btn {
	background-color: #0d9424;
	color: #fff;
}
</style>
